package strategy

import (
	"encoding/json"
	"fmt"
	"reflect"
	"strconv"
)

// ParameterType 参数类型
type ParameterType string

const (
	ParamTypeInt    ParameterType = "int"
	ParamTypeFloat  ParameterType = "float"
	ParamTypeString ParameterType = "string"
	ParamTypeBool   ParameterType = "bool"
	ParamTypeArray  ParameterType = "array"
	ParamTypeObject ParameterType = "object"
)

// ParameterValidator 参数验证器
type ParameterValidator interface {
	Validate(value interface{}) error
}

// IntValidator 整数验证器
type IntValidator struct {
	Min *int `json:"min"`
	Max *int `json:"max"`
}

func (v *IntValidator) Validate(value interface{}) error {
	val, ok := value.(int)
	if !ok {
		if floatVal, ok := value.(float64); ok {
			val = int(floatVal)
		} else {
			return fmt.Errorf("参数值必须是整数")
		}
	}
	
	if v.Min != nil && val < *v.Min {
		return fmt.Errorf("参数值不能小于 %d", *v.Min)
	}
	if v.Max != nil && val > *v.Max {
		return fmt.Errorf("参数值不能大于 %d", *v.Max)
	}
	return nil
}

// FloatValidator 浮点数验证器
type FloatValidator struct {
	Min *float64 `json:"min"`
	Max *float64 `json:"max"`
}

func (v *FloatValidator) Validate(value interface{}) error {
	val, ok := value.(float64)
	if !ok {
		if intVal, ok := value.(int); ok {
			val = float64(intVal)
		} else {
			return fmt.Errorf("参数值必须是数字")
		}
	}
	
	if v.Min != nil && val < *v.Min {
		return fmt.Errorf("参数值不能小于 %f", *v.Min)
	}
	if v.Max != nil && val > *v.Max {
		return fmt.Errorf("参数值不能大于 %f", *v.Max)
	}
	return nil
}

// StringValidator 字符串验证器
type StringValidator struct {
	MinLength *int     `json:"min_length"`
	MaxLength *int     `json:"max_length"`
	Pattern   *string  `json:"pattern"`
	Options   []string `json:"options"`
}

func (v *StringValidator) Validate(value interface{}) error {
	val, ok := value.(string)
	if !ok {
		return fmt.Errorf("参数值必须是字符串")
	}
	
	if v.MinLength != nil && len(val) < *v.MinLength {
		return fmt.Errorf("字符串长度不能小于 %d", *v.MinLength)
	}
	if v.MaxLength != nil && len(val) > *v.MaxLength {
		return fmt.Errorf("字符串长度不能大于 %d", *v.MaxLength)
	}
	
	if len(v.Options) > 0 {
		found := false
		for _, option := range v.Options {
			if val == option {
				found = true
				break
			}
		}
		if !found {
			return fmt.Errorf("参数值必须是以下选项之一: %v", v.Options)
		}
	}
	
	return nil
}

// BoolValidator 布尔值验证器
type BoolValidator struct{}

func (v *BoolValidator) Validate(value interface{}) error {
	_, ok := value.(bool)
	if !ok {
		return fmt.Errorf("参数值必须是布尔值")
	}
	return nil
}

// ParameterConfig 参数配置
type ParameterConfig struct {
	Name         string             `json:"name"`         // 参数名
	Type         ParameterType      `json:"type"`         // 参数类型
	DefaultValue interface{}        `json:"default_value"` // 默认值
	Required     bool               `json:"required"`     // 是否必需
	Description  string             `json:"description"`  // 参数描述
	Label        string             `json:"label"`        // 显示标签
	Group        string             `json:"group"`        // 参数分组
	Order        int                `json:"order"`        // 显示顺序
	Validator    ParameterValidator `json:"-"`            // 验证器
	ValidatorConfig json.RawMessage `json:"validator"`    // 验证器配置
}

// ConfigManager 配置管理器
type ConfigManager struct {
	schemas map[string][]*ParameterConfig // 策略类型对应的参数配置模式
}

// NewConfigManager 创建配置管理器
func NewConfigManager() *ConfigManager {
	return &ConfigManager{
		schemas: make(map[string][]*ParameterConfig),
	}
}

// RegisterParameterSchema 注册参数配置模式
func (cm *ConfigManager) RegisterParameterSchema(strategyType string, params []*ParameterConfig) error {
	if strategyType == "" {
		return fmt.Errorf("策略类型不能为空")
	}
	
	// 验证参数配置
	for _, param := range params {
		if err := cm.validateParameterConfig(param); err != nil {
			return fmt.Errorf("参数配置验证失败 [%s]: %v", param.Name, err)
		}
	}
	
	cm.schemas[strategyType] = params
	return nil
}

// GetParameterSchema 获取参数配置模式
func (cm *ConfigManager) GetParameterSchema(strategyType string) ([]*ParameterConfig, error) {
	schema, exists := cm.schemas[strategyType]
	if !exists {
		return nil, fmt.Errorf("未找到策略类型 %s 的参数配置模式", strategyType)
	}
	return schema, nil
}

// ValidateParameters 验证参数
func (cm *ConfigManager) ValidateParameters(strategyType string, parameters map[string]interface{}) error {
	schema, err := cm.GetParameterSchema(strategyType)
	if err != nil {
		return err
	}
	
	// 验证必需参数
	for _, param := range schema {
		value, exists := parameters[param.Name]
		
		if param.Required && !exists {
			return fmt.Errorf("必需参数 [%s] 缺失", param.Name)
		}
		
		if exists {
			// 验证参数值
			if err := cm.validateParameterValue(param, value); err != nil {
				return fmt.Errorf("参数 [%s] 验证失败: %v", param.Name, err)
			}
		}
	}
	
	return nil
}

// FillDefaultValues 填充默认值
func (cm *ConfigManager) FillDefaultValues(strategyType string, parameters map[string]interface{}) (map[string]interface{}, error) {
	schema, err := cm.GetParameterSchema(strategyType)
	if err != nil {
		return nil, err
	}
	
	result := make(map[string]interface{})
	
	// 复制现有参数
	for k, v := range parameters {
		result[k] = v
	}
	
	// 填充默认值
	for _, param := range schema {
		if _, exists := result[param.Name]; !exists && param.DefaultValue != nil {
			result[param.Name] = param.DefaultValue
		}
	}
	
	return result, nil
}

// ConvertParameterTypes 转换参数类型
func (cm *ConfigManager) ConvertParameterTypes(strategyType string, parameters map[string]interface{}) (map[string]interface{}, error) {
	schema, err := cm.GetParameterSchema(strategyType)
	if err != nil {
		return nil, err
	}
	
	result := make(map[string]interface{})
	
	for _, param := range schema {
		value, exists := parameters[param.Name]
		if !exists {
			continue
		}
		
		convertedValue, err := cm.convertValue(value, param.Type)
		if err != nil {
			return nil, fmt.Errorf("转换参数 [%s] 类型失败: %v", param.Name, err)
		}
		
		result[param.Name] = convertedValue
	}
	
	return result, nil
}

// validateParameterConfig 验证参数配置
func (cm *ConfigManager) validateParameterConfig(param *ParameterConfig) error {
	if param.Name == "" {
		return fmt.Errorf("参数名不能为空")
	}
	
	if param.Type == "" {
		return fmt.Errorf("参数类型不能为空")
	}
	
	// 验证默认值类型
	if param.DefaultValue != nil {
		if err := cm.validateValueType(param.DefaultValue, param.Type); err != nil {
			return fmt.Errorf("默认值类型不匹配: %v", err)
		}
	}
	
	return nil
}

// validateParameterValue 验证参数值
func (cm *ConfigManager) validateParameterValue(param *ParameterConfig, value interface{}) error {
	// 类型验证
	if err := cm.validateValueType(value, param.Type); err != nil {
		return err
	}
	
	// 自定义验证器
	if param.Validator != nil {
		return param.Validator.Validate(value)
	}
	
	return nil
}

// validateValueType 验证值类型
func (cm *ConfigManager) validateValueType(value interface{}, paramType ParameterType) error {
	switch paramType {
	case ParamTypeInt:
		switch value.(type) {
		case int, int32, int64, float64:
			return nil
		default:
			return fmt.Errorf("值类型必须是整数")
		}
	case ParamTypeFloat:
		switch value.(type) {
		case float32, float64, int, int32, int64:
			return nil
		default:
			return fmt.Errorf("值类型必须是数字")
		}
	case ParamTypeString:
		if _, ok := value.(string); !ok {
			return fmt.Errorf("值类型必须是字符串")
		}
	case ParamTypeBool:
		if _, ok := value.(bool); !ok {
			return fmt.Errorf("值类型必须是布尔值")
		}
	case ParamTypeArray:
		if reflect.TypeOf(value).Kind() != reflect.Slice {
			return fmt.Errorf("值类型必须是数组")
		}
	case ParamTypeObject:
		if reflect.TypeOf(value).Kind() != reflect.Map {
			return fmt.Errorf("值类型必须是对象")
		}
	default:
		return fmt.Errorf("未知的参数类型: %s", paramType)
	}
	
	return nil
}

// convertValue 转换值类型
func (cm *ConfigManager) convertValue(value interface{}, paramType ParameterType) (interface{}, error) {
	switch paramType {
	case ParamTypeInt:
		return cm.convertToInt(value)
	case ParamTypeFloat:
		return cm.convertToFloat(value)
	case ParamTypeString:
		return cm.convertToString(value)
	case ParamTypeBool:
		return cm.convertToBool(value)
	default:
		return value, nil
	}
}

// convertToInt 转换为整数
func (cm *ConfigManager) convertToInt(value interface{}) (int, error) {
	switch v := value.(type) {
	case int:
		return v, nil
	case int32:
		return int(v), nil
	case int64:
		return int(v), nil
	case float64:
		return int(v), nil
	case float32:
		return int(v), nil
	case string:
		return strconv.Atoi(v)
	default:
		return 0, fmt.Errorf("无法转换为整数: %v", value)
	}
}

// convertToFloat 转换为浮点数
func (cm *ConfigManager) convertToFloat(value interface{}) (float64, error) {
	switch v := value.(type) {
	case float64:
		return v, nil
	case float32:
		return float64(v), nil
	case int:
		return float64(v), nil
	case int32:
		return float64(v), nil
	case int64:
		return float64(v), nil
	case string:
		return strconv.ParseFloat(v, 64)
	default:
		return 0, fmt.Errorf("无法转换为浮点数: %v", value)
	}
}

// convertToString 转换为字符串
func (cm *ConfigManager) convertToString(value interface{}) (string, error) {
	switch v := value.(type) {
	case string:
		return v, nil
	case int:
		return strconv.Itoa(v), nil
	case float64:
		return strconv.FormatFloat(v, 'f', -1, 64), nil
	case bool:
		return strconv.FormatBool(v), nil
	default:
		return fmt.Sprintf("%v", value), nil
	}
}

// convertToBool 转换为布尔值
func (cm *ConfigManager) convertToBool(value interface{}) (bool, error) {
	switch v := value.(type) {
	case bool:
		return v, nil
	case string:
		return strconv.ParseBool(v)
	case int:
		return v != 0, nil
	case float64:
		return v != 0, nil
	default:
		return false, fmt.Errorf("无法转换为布尔值: %v", value)
	}
}

// GetAllStrategyTypes 获取所有策略类型
func (cm *ConfigManager) GetAllStrategyTypes() []string {
	types := make([]string, 0, len(cm.schemas))
	for strategyType := range cm.schemas {
		types = append(types, strategyType)
	}
	return types
}

// 全局配置管理器实例
var globalConfigManager = NewConfigManager()

// GetConfigManager 获取全局配置管理器
func GetConfigManager() *ConfigManager {
	return globalConfigManager
}